﻿using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using Presentation.Infrastructure;

namespace Presentation
{
    public class LoginViewModel : ViewModelBase
    {
        private bool _isOpeningSession;
        private bool _eventsHooked;
        private string _selectedUser;
        private readonly ObservableCollection<string> _users;
        private readonly SimpleCommand _openSessionCommand;
        
        public bool IsOpeningSession
        {
            get { return _isOpeningSession; }
            set
            {
                _isOpeningSession = value;
                this.NotifyPropertyChanged(o => o.IsOpeningSession); 
            }
        }

        public string SelectedUser
        {
            get { return _selectedUser; }
            set
            {
                _selectedUser = value;
                this.NotifyPropertyChanged(o => o.SelectedUser);
                RefreshCommands();
            }
        }

        public ObservableCollection<string> Users
        {
            get { return _users; }
        }

        public ICommand OpenSessionCommand
        {
            get { return _openSessionCommand; }
        }

        public LoginViewModel()
        {
            _isOpeningSession = false;
            
            _users = new ObservableCollection<string> {"Opérateur"};

            _openSessionCommand = new SimpleCommand(OnOpenSessionCommandExecuted, OnOpenSessionCommandCanExecute);
        }

        private void HookEvents()
        {
            if (_eventsHooked == false)
            {
                ProxyClient.Client.InnerChannel.Opened +=
                    (sender, e) => Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal,
                                                                       new Action(() =>
                                                                                      {
                                                                                          IsOpeningSession = false;
                                                                                          OnLoginSucceed(new EventArgs());
                                                                                      }));

                ProxyClient.Client.InnerChannel.Closing +=
                    (sender, e) => Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal,
                                                                       new Action(() => NavigationService.Instance.NavigateTo(typeof(LoginView))));
                _eventsHooked = true;
            }
        }

        private void OnLoginSucceed(EventArgs e)
        {
            Application.Current.Dispatcher.Invoke(new Action<EventArgs>(arg => NavigationService.Instance.NavigateTo(typeof(DashboardView))), e);

        }

        protected override void RefreshCommands()
        {
            _openSessionCommand.RaiseCanExecuteChanged();
        }

        private bool OnOpenSessionCommandCanExecute(object obj)
        {
            return !String.IsNullOrEmpty(SelectedUser) && !IsOpeningSession;
        }

        private void OnOpenSessionCommandExecuted(object obj)
        {
            IsOpeningSession = true;
            RefreshCommands();
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                                                                      {
                                                                          HookEvents();

                                                                          ProxyClient.CurrentUser = SelectedUser;
                                                                          ProxyClient.Client.BeginOpenSession(ProxyClient.CurrentUser, null, null);
                                                                      }), DispatcherPriority.Background);

        }
    }
}
